<template>
  <div>
    <!-- title -->
    <div class="title-bar">
      <template v-if="!$common.isEmpty(currentAiChatConversation)">
        <span class="title-text">{{ currentAiChatConversation.title }}</span>
      </template>
    </div>

    <!-- 聊天记录 -->
    <div class="msg-container">
      <template v-if="!$common.isEmpty(currentAiChatConversation)">
        <div v-for="(item, index) in aiChatMessageList"
             :class="['msg-one', item.type === 'assistant' ? 'message-left' : 'message-right']"
             :key="item.id ? item.id : index">
          <!-- 头像 -->
          <div>
            <n-avatar :src="item.type === 'assistant' ? aiCover : store.avatar"
                      :size="40"
                      style="cursor: pointer"
                      @click="openFriendCircle(item.fromId, item.avatar)" />
          </div>

          <!-- 文本消息 -->
          <div class="message" v-html="item.contentHtml"></div>

          <!-- 时间 -->
          <div class="msg-date" v-if="!$common.isEmpty(item.createTime)">
            {{ $common.getDateDiff(item.createTime) }}
          </div>
        </div>
      </template>
    </div>

    <!-- 输入框 -->
    <div class="input-section">
      <!-- 功能栏 -->
      <div class="toolbar" style="align-items: center;">
        上下文  <el-switch
        v-model="useContexValue"
        class="mt-2"
        style="margin-left: 24px"
        inline-prompt
        :active-value=true
        :inactive-value=false
        :active-icon="Check"
        :inactive-icon="Close"
      />
      </div>

      <!-- 输入框 -->
      <textarea @keydown="send"
                v-model="msg"
                maxlength="100000"
                spellcheck="false"
                class="message-content"></textarea>

      <!-- 发送 -->
      <div class="message-send">
        <span class="shortcut-info">Ctrl+Enter：换行 | Enter：发送</span>
        <el-button @click="doSend" type="primary" :loading="buttonLoading">发送</el-button>
      </div>
    </div>
  </div>
</template>

<script setup>
import MarkdownIt from 'markdown-it';
import { ref, watch, onMounted, nextTick } from 'vue';
import { createDiscreteApi, NAvatar, NPopover, NImage, NPopconfirm, NButton } from "naive-ui";
import * as $common from "@/utils/common";
import {listAiChatMessage, sendChatMessageCall, sendChatMessageStream} from "@/api/ai/aiChatMessage";
import useUserStore from "@/store/modules/user";
import aiCover from '@/assets/file/ai.jpeg';
import { ElMessage } from "element-plus";
import { Check, Close } from '@element-plus/icons-vue'
import {imgShow} from "@/views/weblogFront/im/hooks/imUtil";
import {listAiChatModel} from "@/api/ai/aiChatModel";

// 初始化 markdown-it
const markdownParser = new MarkdownIt({ html: true, linkify: true,breaks: true  });
const aiChatMessageList = ref([]);
const msg = ref('');
const store = useUserStore();
const conversationInAbortController = ref();
const buttonLoading = ref(false);
const useContexValue = ref(true);


const props = defineProps({
  currentAiChatConversation: Object,
  friends: Object,
  imageList: Array
});

const emit = defineEmits(['openFriendCircle']);

onMounted(async () => {
  const response = await listAiChatMessage({ conversationId: props.currentAiChatConversation.id });
  aiChatMessageList.value = response.rows;
  await scrollMsgContainerToBottom();
});

const highlight = () => {
  let attributes = {
    autocomplete: "off",
    autocorrect: "off",
    autocapitalize: "off",
    spellcheck: "false",
    contenteditable: "false",
  };

  let preElements = document.querySelectorAll("pre");
  preElements.forEach(function (item, i) {
    let preCode = item.querySelector("code");
    let classNameArr = preCode.className.split(" ");

    let lang = classNameArr.find(className => className.startsWith("language-"));
    lang = lang ? lang.replace("language-", "") : "";

    let language = hljs.getLanguage(lang.toLowerCase());
    if (!language) {
      let autoLanguage = hljs.highlightAuto(preCode.textContent);
      preCode.classList.remove(`language-${lang}`);
      lang = autoLanguage.language || "plaintext";
      preCode.classList.add(`language-${lang}`);
    }

    item.classList.add("highlight-wrap");
    for (let key in attributes) {
      item.setAttribute(key, attributes[key]);
    }
    preCode.setAttribute("data-rel", lang.toUpperCase());
    preCode.classList.add(lang.toLowerCase());

    // 使用 highlightElement 避免格式问题
    hljs.highlightElement(preCode);
  });

  let codeBlocks = document.querySelectorAll("pre code");
  codeBlocks.forEach(function (block, i) {
    block.setAttribute("id", "hljs-" + i);

    let copyButton = document.createElement("a");
    copyButton.className = "copy-code";
    copyButton.href = "javascript:";
    copyButton.setAttribute("data-clipboard-target", "#hljs-" + i);
    copyButton.innerHTML = '<i class="fa fa-clipboard" aria-hidden="true"></i>';

    block.parentNode.insertBefore(copyButton, block.nextSibling);
  });

  new ClipboardJS(".copy-code");

  let entryContent = document.querySelector(".entry-content");
  if (entryContent) {
    let tables = entryContent.querySelectorAll(":scope > table");
    tables.forEach(function (table) {
      let wrapper = document.createElement("div");
      wrapper.className = 'table-wrapper';
      table.parentNode.insertBefore(wrapper, table);
      wrapper.appendChild(table);
    });
  }
};



watch(aiChatMessageList, async (newList) => {
  newList.forEach(item => {
    item.contentHtml = markdownParser.render(item.content);
  });
  await nextTick(highlight); // 等待内容渲染后再调用 highlight
}, { immediate: true });


const openFriendCircle = (userId, avatar) => {
  emit('openFriendCircle', userId, avatar);
};

const send = (e) => {
  if ((e.ctrlKey || e.shiftKey) && e.keyCode === 13) {
    e.preventDefault();
    msg.value += '\n';
  } else if (e.keyCode === 13) {
    e.preventDefault();
    doSend();
  }
};

const formatReceive = async (item) => {
  item.contentHtml = markdownParser.render(item.content);
  await nextTick(highlight);
};

const doSend=async ()=>{
  buttonLoading.value = true;
  let sendmsg={
    conversationId:props.currentAiChatConversation.id,
    userId:"1000000000000000000",
    type:"user",
    model:"gpt-3.5-turbo",
    modelId:11,
    content:msg.value,
    useContex:useContexValue.value,
    deleted:0,
    contentHtml:""}
  aiChatMessageList.value.push(sendmsg)
  await formatReceive(aiChatMessageList.value[aiChatMessageList.value.length - 1]);
  await scrollMsgContainerToBottom();
  let sendmail = msg.value
  msg.value = '';
  let response = await sendChatMessageCall({
    conversationId:props.currentAiChatConversation.id,
    content:sendmail,
    useContext:useContexValue.value
  });
  aiChatMessageList.value.push(response.data)
  await formatReceive(aiChatMessageList.value[aiChatMessageList.value.length - 1]);
  await scrollMsgContainerToBottom();
  buttonLoading.value = false;
}




const doSend1 = async () => {
  let isFirstChunk = true;
  conversationInAbortController.value = new AbortController();
  let sendmsg={
    conversationId:props.currentAiChatConversation.id,
    userId:"1000000000000000000",
    type:"user",
    model:"gpt-3.5-turbo",
    modelId:11,
    content:msg.value,
    useContex:useContexValue.value,
    deleted:0,
    contentHtml:""}
  let sendmail = msg.value
  msg.value = '';
  aiChatMessageList.value.push(sendmsg)
  await formatReceive(aiChatMessageList.value[aiChatMessageList.value.length - 1]);
  await scrollMsgContainerToBottom();
  await sendChatMessageStream(
    props.currentAiChatConversation.id,
    sendmail,
    conversationInAbortController.value,
    useContexValue.value,
    async (res) => {
      const { code, data } = JSON.parse(res.data);

      if (isFirstChunk) {
        isFirstChunk = false;
        aiChatMessageList.value.push(data.receive);
        console.log(data.receive.content)
        await formatReceive(data.receive);
      }else {
        aiChatMessageList.value[aiChatMessageList.value.length - 1].content += data.receive.content;
        await formatReceive(aiChatMessageList.value[aiChatMessageList.value.length - 1]);
        await scrollMsgContainerToBottom();
      }
    },
    (error) => {
      ElMessage.error(`对话异常! ${error}`);
      stopStream();
      msg.value = '';
    },
    () => {
      stopStream();
      msg.value = '';
    }
  );
};

const stopStream = () => {
  if (conversationInAbortController.value) {
    conversationInAbortController.value.abort();
  }
};

const scrollMsgContainerToBottom = () => {
  nextTick(() => {
    const container = document.querySelector('.msg-container');
    if (container) {
      container.scrollTop = container.scrollHeight
    }
  })
};
</script>


<style scoped>
.title-bar {
  height: 60px;
  background-color: var(--maxWhite);
}

.title-text {
  line-height: 60px;
  margin-left: 20px;
  font-size: 18px;
}

.msg-container {
  background: var(--midWhite);
  overflow-y: scroll;
  height: calc(100% - 240px);
}

.msg-one {
  margin: 15px 20px;
  display: flex;
  align-items: flex-start;
}

.message {
  max-width: 50%;
  padding: 5px 10px;
  line-height: 25px;
  word-break: break-all;
  color: var(--black);
  margin: 0 12px;
}

.message-left .message {
  background-color: var(--white);
  border-radius: 0 4px 4px 4px;
}

.message-right {
  flex-direction: row-reverse;
}

.message-right .message {
  background-color: var(--messageColor);
  border-radius: 4px 0 4px 4px;
}

.msg-date {
  font-size: 12px;
  color: var(--greyFont);
}

.input-section {
  height: 180px;
}

.toolbar {
  padding: 10px 15px;
  display: flex;
}

.message-content {
  width: calc(100% - 30px);
  margin: 0 15px;
  height: calc(100% - 100px);
  resize: none;
  font-size: 18px;
  border: none;
  outline: none
}

.message-send {
  float: right;
  padding: 0px 30px 15px;
  margin-bottom: 15px;
}

.shortcut-info {
  color: var(--greyFont);
  margin-right: 15px;
  font-size: 12px;
}
</style>
